import _ from 'lodash';
import { Dialog, EventBus, Loading, Notify } from 'quasar';
import axios, { type AxiosRequestConfig } from 'axios';

export default class LCC {
  readonly eventBus: EventBus = new EventBus();

  constructor() {
    // 构造函数中不再初始化模拟数据
    _.defer(() => {
      // const $q = useQuasar()
      // window['$q'] = $q
      window['Notify'] = Notify;
      window['Dialog'] = Dialog;
      window['Loading'] = Loading;
    });
  }

  /**
   * 轻量级提示信息
   * @param message 消息内容
   * @param option 消息类型，默认为 'info'
   */
  public msg(message: string, option: MsgOption = {}): void {
    console.trace(message);
    if (!option) {
      option = {};
    }

    _.defaults(option, {
      type: 'info',
      timeout: 3000,
      position: 'top',
      html: false,
      multiLine: false
    });

    if (option.type === 'success') {
      option.type = 'positive' as any;

    } else if (option.type === 'warning') {
      option.type = 'warning';

    } else if (option.type === 'info') {
      option.type = '' as any;

    } else if (option.type === 'error') {
      option.type = 'negative' as any;
    }

    Notify.create({
      type: option.type as any,
      message: option.html ? this.processMessage(message) : message,
      position: option.position as any,
      timeout: option.timeout as any,
      multiLine: option.multiLine as any,
      html: option.html as any,
      actions: [{ icon: 'close', color: 'white' }]
    });
  }

  /**
   * 处理消息中的换行符，将 \n 转换为 <br> 标签
   * @param text 原始文本
   * @returns 处理后的文本
   */
  private processMessage(text: string): string {
    return text.replace(/\n/g, '<br>');
  }


  /**
   * 弹出用户必须点击确认的错误信息
   */
  async showErrorDialog(msgOrTitle: string, msg?: string): Promise<void> {
    return new Promise((resolve) => {
      Dialog.create({
        title: msg ? msgOrTitle : '错误',
        message: msg ? this.processMessage(msg) : this.processMessage(msgOrTitle),
        html: true, // 启用 HTML 支持以显示 <br> 标签
        ok: {
          label: '确定',
          color: 'negative'
        },
        persistent: true
      }).onOk(() => {
        resolve();
      });
    });
  }

  /**
   * 弹出用户必须确认的提示信息
   */
  public showInfoDialog(content: string, option: ShowDialogOption = {
    html: true,
    showCancelButton: false,
    showClose: false,
    closeOnClickModal: false,
    customClass: ''
  }): Promise<void> {
    return new Promise((resolve) => {
      const dialogOptions: any = {
        message: this.processMessage(content),
        ok: {
          label: '确定',
          color: 'primary'
        },
        persistent: !option.closeOnClickModal
      };

      if (option.showCancelButton) {
        dialogOptions.cancel = {
          label: '取消',
          flat: true
        };
      }

      if (typeof option.html === 'boolean') {
        dialogOptions.html = option.html;
      }

      if (option.showClose) {
        dialogOptions.showClose = true;
      }

      if (option.customClass) {
        dialogOptions.class = option.customClass;
      }

      Dialog.create(dialogOptions).onOk(() => {
        resolve();
      }).onCancel(() => {
        resolve();
      });
    });
  }

  /**
   * 弹出确认对话框
   * @param msg 消息内容
   */
  public confirm(msg: string): Promise<void> {
    return new Promise((resolve, reject) => {
      Dialog.create({
        message: this.processMessage(msg),
        html: true, // 启用 HTML 支持以显示 <br> 标签
        ok: {
          label: '确定',
          color: 'primary'
        },
        cancel: {
          label: '取消',
          flat: true
        },
        persistent: true
      }).onOk(() => {
        resolve();
      }).onDismiss(() => {
        reject('User cancel');
      }).onCancel(() => {
        reject('User cancel');
      });
    });
  }

  public hideLoading(group?: string) {
    Loading.hide(group);
  }

  /**
   * 全局 "正在载入..." 对话框
   */
  public showLoading(msg?: string, option = {
    group: '',
    timeout: 0,
    delay: 0

  }): CloseFn {
    Loading.show({
      message: msg || 'Loading...',
      boxClass: 'bg-grey-2 text-grey-9',
      spinnerSize: 40,
      spinnerColor: 'primary',
      delay: option.delay,
      group: option.group
    });

    const closeFn = () => {
      Loading.hide(option.group);
    };

    if (option.timeout) {
      setTimeout(closeFn, option.timeout);
    }

    return closeFn;
  }

  emit(eventName: string, ...objects: any[]) {
    this.eventBus.emit(eventName, ...objects);
  }

  on(eventName: string, cb: (...args: any[]) => void) {
    this.eventBus.on(eventName, cb);
  }

  off(eventName: string, cb: (...args: any[]) => void) {
    this.eventBus.off(eventName, cb);
  }

  async httpGet<T = any>(url: string, config?: RequestConfig<T>): Promise<T> {
    return axios.get(url, config as any).then(response => response.data);
  }
}

type CloseFn = () => void

interface MsgOption {
  type?: 'success' | 'warning' | 'info' | 'error',
  timeout?: number,
  position?: string,
  html?: boolean,
  color?: string,
  multiLine?: boolean
}

interface RequestConfig<T = any> extends AxiosRequestConfig<T> {
  ignoreErrorDialog?: boolean;
  isRawUrl?: boolean;
}

interface ShowDialogOption {
  html?: boolean;
  showCancelButton?: boolean;
  showClose?: boolean;
  closeOnClickModal?: boolean;
  customClass?: string;
}
